package top.chenyaohua.init.imp;

import com.google.auto.service.AutoService;
import org.w3c.dom.*;
import org.xml.sax.SAXException;
import top.chenyaohua.annotion.Repository;
import top.chenyaohua.asm.BeanMetadata;
import top.chenyaohua.beans.MapperBean;
import top.chenyaohua.context.BeanFactory;
import top.chenyaohua.init.abstractInit.AbstractInitExecution;
import top.chenyaohua.utils.AnnotationUtils;
import top.chenyaohua.utils.InitExecutionUtils;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 解析xml 获取SQL
 */
@AutoService(AbstractInitExecution.class)
public class DaoMapperParseInit extends AbstractInitExecution {


    public DaoMapperParseInit () {
        super(3);
    }

    @Override
    public boolean init () {
        String name = Repository.class.getName();
        Stream<BeanMetadata> stream = BeanFactory.getBeanMetadata().stream().filter(x -> AnnotationUtils.isExist(x.getAnnotations(), name));

        if(stream == null){
            return false;
        }


        InitExecutionUtils.setMapper(getMapperBeans());
/*        List<BeanMetadata> collect = stream.collect(Collectors.toList());
        for (BeanMetadata bean : collect) {
            List<AnnotationMetadata> annotations = bean.getAnnotations();
            String className = bean.getClassName();

        }*/


        return false;
    }

    private List<MapperBean> getMapperBeans () {
        List<MapperBean> mapperBeans = new ArrayList<>();
        DocumentBuilderFactory documentBuilderFactory=DocumentBuilderFactory.newInstance();
        try {
            DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();

            URI uri = Objects.requireNonNull(Thread.currentThread().getContextClassLoader().getResource("")).toURI();
            List<File> collect = Files.walk(Paths.get(uri)).filter(x->x.toString().endsWith(".xml")).map(Path::toFile).collect(Collectors.toList());
            Iterator<File> iterator = collect.iterator();
            while (iterator.hasNext()) {
                File next = iterator.next();
                InputStream inputStream = Files.newInputStream(next.toPath());
                Document parse = documentBuilder.parse(inputStream);
                Element documentElement = parse.getDocumentElement();
                //获取空间名
                String namespace = documentElement.getAttribute("namespace");
                NodeList childNodes = documentElement.getChildNodes();

                MapperBean mapperBean = new MapperBean();
                mapperBean.setNamespace(namespace);

                Map<String,String> param = null;
                Map<String, Map<String,String>> params = new HashMap<>();

                for (int i = 0; i < childNodes.getLength(); i++) {

                    param = new HashMap<>();

                    //获取sql执行类型  (标签名称)
                    Node item = childNodes.item(i);
                    String nodeName = item.getNodeName();
                    switch (nodeName){
                        case "select":
                        case "delete":
                        case "insert":
                        case "update":
                            param.put("type",nodeName);
                            break;
                        default:
                            continue;
                    }

                    NamedNodeMap attributes = item.getAttributes();
                    //获取id
                    Node id = attributes.getNamedItem("id");
                    String idValue = id.getNodeValue();
                    params.put(idValue,param);
                    //获取返回值类型resultType
                    Node resultType = attributes.getNamedItem("resultType");
                    param.put("resultType",resultType.getNodeValue());
                    String textContent = item.getTextContent();
                    param.put("sql",textContent.trim());

                    mapperBean.setParams(params);
                    mapperBeans.add(mapperBean);
                }

            }


        } catch (ParserConfigurationException | SAXException | IOException | URISyntaxException e) {
            e.printStackTrace();
        }
        return mapperBeans;
    }
}
